package org.jsola.contract.service.impl;

import com.timevale.esign.sdk.tech.bean.*;
import com.timevale.esign.sdk.tech.bean.result.FileDigestSignResult;
import com.timevale.esign.sdk.tech.impl.constants.LegalAreaType;
import com.timevale.esign.sdk.tech.impl.constants.OrganRegType;
import com.timevale.esign.sdk.tech.impl.constants.SignType;
import lombok.extern.slf4j.Slf4j;
import org.jsola.contract.common.ESignHelper;
import org.jsola.contract.constant.*;
import org.jsola.contract.entity.AccountDO;
import org.jsola.contract.entity.SealPositionDO;
import org.jsola.contract.exception.ContractException;
import org.jsola.contract.service.IAccountService;
import org.jsola.contract.service.IThirdSignService;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.List;
import java.util.UUID;

import static org.jsola.user.constant.UserConstants.DEFAULT_SITE_ID;

/**
 * @author JanusMix
 */
@Slf4j
@Service("contractThirdSignService")
public class ThirdSignServiceImpl implements IThirdSignService {

    @Autowired
    private IAccountService accountService;
    @Autowired
    private ThirdSignClientFactory thirdSignClientFactory;

    @Override
    public AccountDO addPersonAccount(String userId, String name, String phone, String idNo, String personArea, TokenUser tokenUser) {
        AccountDO accountDO = accountService.findAccount(AccountType.PERSON, userId);
        if (accountDO != null && accountDO.getReal()) {
            return accountDO;
        }
        PersonBean personBean = new PersonBean();
        personBean.setName(name);
        personBean.setIdNo(idNo);
        personBean.setMobile(phone);
        personBean.setPersonArea(LegalAreaType.MAINLAND);
        //第三方注册
        String accountId = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
        if (accountDO != null) {
            //更新账户id和实名状态
            accountDO.setAccountId(accountId);
            accountDO.setReal(Boolean.TRUE);
            accountDO.setIdNo(idNo);
            accountDO.setMobile(phone);
            accountDO.setName(name);
            accountDO.setPersonArea(personArea);
            accountService.updateById(accountDO, DEFAULT_SITE_ID, userId);
            return accountDO;
        } else {
            accountDO = new AccountDO();
            accountDO.setAccountId(accountId);
            accountDO.setIdNo(idNo);
            accountDO.setPersonArea(PersonAreaType.MAINLAND.getValue());
            accountDO.setMemberId(userId);
            accountDO.setName(name);
            accountDO.setMobile(phone);
            accountDO.setType(AccountType.PERSON.getValue());
            accountDO.setReal(Boolean.TRUE);
            //保存账户表
            return accountService.save(accountDO, DEFAULT_SITE_ID, userId);
        }
    }

    @Override
    public AccountDO addEnterpriseAccount(String enterpriseId, String name, String regType, String organCode,
                                          String legalName, String agentIdNo, String email, TokenUser tokenUser) {
        AccountDO accountDO = accountService.findAccount(AccountType.ENTERPRISE, enterpriseId);
        //第三方注册
        if (accountDO != null) {
            return accountDO;
        }
        accountDO = new AccountDO();
        accountDO.setAccountId(email);
        accountDO.setEmail(email);
        accountDO.setMemberId(enterpriseId);
        accountDO.setName(name);
        accountDO.setType(AccountType.ENTERPRISE.getValue());
        accountDO.setUserType(2);
        accountDO.setOrganCode(organCode);
        accountDO.setLegalName(legalName);
        accountDO.setAgentIdNo(agentIdNo);
        accountDO.setRegType(regType);
        accountDO.setReal(Boolean.TRUE);
        //保存账户表
        return accountService.save(accountDO, DEFAULT_SITE_ID, "system");
    }

    @Override
    public void sendSignCode(String accountId, TokenUser tokenUser) {
        ESignHelper eSignHelper = thirdSignClientFactory.getClient(tokenUser);
        eSignHelper.sendSignCode(accountId);
    }

    @Override
    public FileDigestSignResult localSafeSignPDF(String accountId, String sealData, byte[] fileStream,
                                                 List<SealPositionDO> positions, SealType sealType, String code, TokenUser tokenUser) {
        //文件流
        SignPDFFileBean signPDFFileBean = new SignPDFFileBean();
        signPDFFileBean.setBytes(fileStream);

        SealPositionDO sealPositionDO = positions.get(0);
        //签署位置
        PosBean posBean = new PosBean();
        posBean.setPosX(Float.parseFloat(sealPositionDO.getSealPositionX()));
        posBean.setPosY(Float.parseFloat(sealPositionDO.getSealPositionY()));
        posBean.setPosPage(sealPositionDO.getSealPage().toString());
        // 取消时间戳
        posBean.setAddSignTime(Boolean.FALSE);
        posBean.setWidth(159F);
        String base64 = "base64,";
        if (!sealData.contains(base64)) {
            throw new ContractException("签名格式不正确");
        }
        //图片前缀去除
        sealData = sealData.substring(sealData.indexOf(base64) + 7);
        ESignHelper eSignHelper = thirdSignClientFactory.getClient(tokenUser);
        //调用第三方签署
        return eSignHelper.localSignPDF(accountId, sealData, signPDFFileBean, posBean, SignType.Single, code);
    }

    @Override
    public FileDigestSignResult localSafeSignPDF(String accountId, String sealData, byte[] fileStream,
                                                 List<SealPositionDO> positions, SealType sealType, TokenUser tokenUser) {
        return localSafeSignPDF(accountId, sealData, fileStream, positions, sealType, 159F, tokenUser);
    }

    @Override
    public FileDigestSignResult localSafeSignPDF(String accountId, String sealData, byte[] fileStream,
                                                 List<SealPositionDO> positions, SealType sealType,
                                                 float width, TokenUser tokenUser) {
        log.info("合同日志追踪===>开始调用第三方签署，userId:{},accountId:{},sealType:{},合同md5:{}",
                tokenUser.getUserId(), accountId, sealType.getDesc(),
                DigestUtils.md5DigestAsHex(fileStream));

        FileDigestSignResult fileDigestSignResult = new FileDigestSignResult();
        String base64 = "base64,";
        if (!sealData.contains(base64)) {
            log.error("签名信息：{}", sealData);
            throw new ContractException("签名格式不正确");
        }
        //图片前缀去除
        sealData = sealData.substring(sealData.indexOf(base64) + 7);
        for (SealPositionDO position : positions) {
            //文件流
            SignPDFStreamBean signPDFFileBean = new SignPDFStreamBean();
            signPDFFileBean.setStream(fileStream);
            //签署位置
            PosBean posBean = new PosBean();
            posBean.setPosX(Float.parseFloat(position.getSealPositionX()));
            posBean.setPosY(Float.parseFloat(position.getSealPositionY()));
            posBean.setPosPage(position.getSealPage().toString());
            posBean.setAddSignTime(Boolean.FALSE);
            posBean.setWidth(width);
            ESignHelper eSignHelper = thirdSignClientFactory.getClient(tokenUser);
            //调用第三方签署
            fileDigestSignResult = eSignHelper.localSignPDF(accountId, sealData, signPDFFileBean, posBean, SignType.Single);
            fileStream = fileDigestSignResult.getStream();
            log.info("合同日志追踪===>根据word模板企业签署，调用第三方签署成功，印章位置：{}, userId:{},accountId:{},合同md5:{}",
                    position.getSealPositionX(), tokenUser.getUserId(), accountId, DigestUtils.md5DigestAsHex(fileStream));
        }
        return fileDigestSignResult;
    }
}
